unit cominginvoiceelement;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  ComCtrls, Buttons, StdCtrls,db, DbCtrls, Grids;

type

  { TfrmComingInvoiceElement }

  TfrmComingInvoiceElement = class(TForm)
    btnGoodsCancel: TBitBtn;
    btnCounterPartiesSelect: TBitBtn;
    btnPrint: TBitBtn;
    btnStoreHousesSelect: TBitBtn;
    btnSave: TBitBtn;
    btnClose: TBitBtn;
    btnGoodsSave: TBitBtn;
    btnGoodsDelete: TBitBtn;
    btnGoodsAdd: TBitBtn;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    lblEdtCounterParty: TLabeledEdit;
    lblEdtStoreHouse: TLabeledEdit;
    lblEdtInvoiceID: TLabeledEdit;
    lblquantity: TLabel;
    lblsum: TLabel;
    PC: TPageControl;
    StringGridGoods: TStringGrid;
    TSGoods: TTabSheet;
    procedure btnGoodsCancelClick(Sender: TObject);
    procedure btnCounterPartiesSelectClick(Sender: TObject);
    procedure btnGoodsDeleteClick(Sender: TObject);
    procedure btnGoodsAddClick(Sender: TObject);
    procedure btnGoodsSaveClick(Sender: TObject);
    procedure btnPrintClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnStoreHousesSelectClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
    procedure checkErrors;
    procedure FormShow(Sender: TObject);
    procedure refreshListOfGoods;
    procedure StringGridGoodsDblClick(Sender: TObject);
    procedure StringGridGoodsKeyPress(Sender: TObject; var Key: char);
    procedure StringGridGoodsSelectCell(Sender: TObject; aCol, aRow: Integer;
      var CanSelect: Boolean);
    procedure StringGridGoodsValidateEntry(sender: TObject; aCol,
      aRow: Integer; const OldValue: string; var NewValue: String);
    procedure updateAllCount;
  private
    { private declarations }
  public
    { public declarations }
    ginvoiceid:Integer;
    invoiceIsNew:Boolean;
  end;

var
  frmComingInvoiceElement: TfrmComingInvoiceElement;
  invoiceChanged:Boolean=False;
  goodsChanged:Boolean=False;
  goodsEditMode:Boolean=False;
implementation

{$R *.lfm}

{ TfrmComingInvoiceElement }
uses main,nomenclatureselect,counterpartiesselect,storehouseselect;

procedure TfrmComingInvoiceElement.updateAllCount;
var
  i,quantity:Integer;
  sum:Currency;
begin
  ///////////Update Summ and Count on the label | and check all entered data
  sum:=0;
  quantity:=0;
  for i:=1 to StringGridGoods.RowCount-1 do begin
    if (StringGridGoods.Cells[2,i]=EmptyStr) OR (StringGridGoods.Cells[3,i]=EmptyStr) OR (StringGridGoods.Cells[4,i]=EmptyStr) then begin
    end else begin
      sum:=sum+(StrToInt(StringGridGoods.Cells[3,i])*StrToCurr(StringGridGoods.Cells[4,i]));
      quantity:=quantity+StrToInt(StringGridGoods.Cells[3,i]);
    end;
  end;
  lblsum.Caption:=CurrToStr(sum);
  lblquantity.Caption:=IntToStr(quantity);
end;

procedure TfrmComingInvoiceElement.refreshListOfGoods;
var
  i,quantity:Integer;
  sum:Currency;
begin
  sum:=0;
  quantity:=0;
  FrmMain.DSComingGoodsView.DataSet.Filter:='invoiceid='+IntToStr(ginvoiceid);
  FrmMain.DSComingGoodsView.DataSet.Filtered:=True;
  FrmMain.DSComingGoodsView.DataSet.Refresh;
  StringGridGoods.Clear;
  StringGridGoods.RowCount:=1;
  StringGridGoods.RowCount:=FrmMain.DSComingGoodsView.DataSet.RecordCount+1;
  FrmMain.DSComingGoodsView.DataSet.First;
  for i:=1 to FrmMain.DSComingGoodsView.DataSet.RecordCount do begin
    StringGridGoods.Cells[1,i]:=FrmMain.DSComingGoodsView.DataSet.FieldByName('id').AsString;
    StringGridGoods.Cells[2,i]:=FrmMain.DSComingGoodsView.DataSet.FieldByName('title').AsString;
    StringGridGoods.Cells[3,i]:=FrmMain.DSComingGoodsView.DataSet.FieldByName('quantity').AsString;
    StringGridGoods.Cells[4,i]:=FrmMain.DSComingGoodsView.DataSet.FieldByName('price').AsString;
    StringGridGoods.Cells[5,i]:=CurrToStr(FrmMain.DSComingGoodsView.DataSet.FieldByName('quantity').AsInteger*FrmMain.DSComingGoodsView.DataSet.FieldByName('price').AsCurrency);
    StringGridGoods.Cells[6,i]:=FrmMain.DSComingGoodsView.DataSet.FieldByName('nomenclatureid').AsString;
    sum:=sum+(FrmMain.DSComingGoodsView.DataSet.FieldByName('quantity').AsInteger*FrmMain.DSComingGoodsView.DataSet.FieldByName('price').AsCurrency);
    quantity:=quantity+FrmMain.DSComingGoodsView.DataSet.FieldByName('quantity').AsInteger;
    FrmMain.DSComingGoodsView.DataSet.Next;
  end;
  lblsum.Caption:=CurrToStr(sum);
  lblquantity.Caption:=IntToStr(quantity);
end;

procedure TfrmComingInvoiceElement.checkErrors;
begin
  //////////////////////////////////////////
  if (lblEdtCounterParty.Text=EmptyStr) OR (lblEdtStoreHouse.Text=EmptyStr) then begin
    btnSave.Enabled:=False;
  end else begin
    btnSave.Enabled:=True;
  end;
  //////////////////////////////////////////
  if (goodsEditMode) then begin
    btnGoodsAdd.Enabled:=False;
    btnGoodsSave.Enabled:=True;
    btnGoodsCancel.Enabled:=True;
    btnGoodsDelete.Enabled:=False;
    btnSave.Enabled:=False;
    btnClose.Enabled:=False;
    btnPrint.Enabled:=False;
  end else begin
    btnGoodsAdd.Enabled:=True;
    btnGoodsSave.Enabled:=False;
    btnGoodsCancel.Enabled:=False;
    btnGoodsDelete.Enabled:=True;
    btnSave.Enabled:=True;
    btnClose.Enabled:=True;
    btnPrint.Enabled:=True;
  end;
  //////////////////////////////////////////
  if NOT invoiceIsNew AND NOT invoiceChanged then begin
    btnSave.Enabled:=False;
    btnCounterPartiesSelect.Enabled:=False;
    btnStoreHousesSelect.Enabled:=False;
  end;
  //////////////////////////////////////////
  if invoiceIsNew then begin
    btnCounterPartiesSelect.Enabled:=True;
    btnStoreHousesSelect.Enabled:=True;
  end else begin
    btnCounterPartiesSelect.Enabled:=False;
    btnStoreHousesSelect.Enabled:=False;
  end;
  //////////////////////////////////////////
  if invoiceIsNew OR invoiceChanged OR goodsChanged then begin
    btnSave.Enabled:=True;
    btnPrint.Enabled:=False;
  end;
  //////////////////////////////////////////
  if (StringGridGoods.RowCount=1) then begin
    btnGoodsDelete.Enabled:=False;
  end;
  //////////////////////////////////////////
  if (lblEdtCounterParty.Text=EmptyStr) OR (lblEdtStoreHouse.Text=EmptyStr) then begin
    btnSave.Enabled:=False;
  end;
end;

procedure TfrmComingInvoiceElement.StringGridGoodsDblClick(Sender: TObject);
begin
  if ((StringGridGoods.SelectedColumn.Title.Caption = 'Номенклатура') AND (StringGridGoods.Cells[1,StringGridGoods.Row]=EmptyStr)) then begin
    FrmMain.clearSelect;
    frmNomenclatureSelect.ShowModal;
    StringGridGoods.Cells[2,StringGridGoods.Row]:=FrmMain.nomenclatureSelectedTitle;
    StringGridGoods.Cells[6,StringGridGoods.Row]:=IntToStr(FrmMain.nomenclatureSelectedId);
  end;
end;

procedure TfrmComingInvoiceElement.StringGridGoodsKeyPress(Sender: TObject;
  var Key: char);
begin
  if StringGridGoods.SelectedColumn.Title.Caption = 'Кількість' then begin
    FrmMain.KeyVerifyInt(Sender,Key);
  end;
  if StringGridGoods.SelectedColumn.Title.Caption = 'Ціна' then begin
    FrmMain.KeyVerifyFloat(Sender,Key);
  end;
end;

procedure TfrmComingInvoiceElement.StringGridGoodsSelectCell(Sender: TObject;
  aCol, aRow: Integer; var CanSelect: Boolean);
begin
  if goodsEditMode then begin
    if StringGridGoods.Row<>aRow then begin
    CanSelect:=False;
    end else begin
    CanSelect:=True;
    end;
  end;
end;

procedure TfrmComingInvoiceElement.StringGridGoodsValidateEntry(
  sender: TObject; aCol, aRow: Integer; const OldValue: string;
  var NewValue: String);
var
  i,quantity:Integer;
  sum:Currency;
begin
  if ((aCol=3) AND (StringGridGoods.Cells[1,aRow]<>EmptyStr) AND (OldValue<>NewValue)) then begin
    StringGridGoods.Cells[7,aRow]:=OldValue;
  end;
  sum:=0;
  quantity:=0;
  ///////////Update Summ and Count on the label | and check all entered data
  for i:=1 to StringGridGoods.RowCount-1 do begin
    if (StringGridGoods.Cells[2,i]=EmptyStr) OR (StringGridGoods.Cells[3,i]=EmptyStr) OR (StringGridGoods.Cells[4,i]=EmptyStr) then begin
      btnGoodsSave.Enabled:=False;
    end else begin
      btnGoodsSave.Enabled:=True;
      sum:=sum+(StrToInt(StringGridGoods.Cells[3,i])*StrToCurr(StringGridGoods.Cells[4,i]));
      quantity:=quantity+StrToInt(StringGridGoods.Cells[3,i]);
    end;
  end;
  lblsum.Caption:=CurrToStr(sum);
  lblquantity.Caption:=IntToStr(quantity);
  ///////////end update and check
  ///////////Update Summ after entering
  if (StringGridGoods.Cells[3,i]<>EmptyStr) AND (StringGridGoods.Cells[4,i]<>EmptyStr) then begin
     StringGridGoods.Cells[5,i]:=CurrToStr(StrToInt(StringGridGoods.Cells[3,i])*StrToCurr(StringGridGoods.Cells[4,i]));
  end;
end;

procedure TfrmComingInvoiceElement.FormCloseQuery(Sender: TObject;
  var CanClose: boolean);
var
  res:Integer;
begin
  if invoiceIsNew OR goodsChanged OR invoiceChanged then begin
    res:=MessageDlg('','Закрити без збереження данних?',mtConfirmation,mbYesNo,0);
    if (res=mrYes) then begin
      if (invoiceIsNew) then begin
        invoiceIsNew:=False;
      end;
      invoiceChanged:=False;
      goodsEditMode:=False;
      FrmMain.history('Прихідна накладна','Вихід без збереження');
    end else begin
        CanClose:=False;
    end;
  end;
  FrmMain.DSComingInvoices.DataSet.Refresh;
end;

procedure TfrmComingInvoiceElement.FormShow(Sender: TObject);
begin
  if invoiceIsNew then begin
    lblEdtCounterParty.Clear;
    lblEdtStoreHouse.Clear;
    lblEdtInvoiceID.Clear;
    StringGridGoods.Clear;
    StringGridGoods.RowCount:=1;
    lblsum.Caption:='';
    lblquantity.Caption:='';
  end else begin
    refreshListOfGoods;
  end;
  checkErrors();
end;

procedure TfrmComingInvoiceElement.btnStoreHousesSelectClick(Sender: TObject);
begin
  frmStoreHouseSelect.ShowModal;
  lblEdtStoreHouse.Text:=FrmMain.storeHouseSelectedTitle;
  invoiceChanged:=True;
  checkErrors();
end;

procedure TfrmComingInvoiceElement.btnPrintClick(Sender: TObject);
begin
  { TODO 2 : Одержувач: додати додаткову інформацію в накладних/ прихідна/вихідна }
  FrmMain.frDBDataSet.DataSource:=FrmMain.DSComingGoodsView;
  FrmMain.purveyor:=lblEdtCounterParty.Text;
  FrmMain.recipient:=lblEdtStoreHouse.Text;
  FrmMain.comingInvoiceID:=lblEdtInvoiceID.Text;
  FrmMain.invoiceID:=IntToStr(ginvoiceid);
  FrmMain.frReport.LoadFromFile(FrmMain.program_dir+'reports\cominginvoice.lrf');
  FrmMain.frReport.ShowReport;
end;

procedure TfrmComingInvoiceElement.btnSaveClick(Sender: TObject);
var
  i:Integer;
  quantity:String;
begin
 if invoiceIsNew then begin
   if lblEdtInvoiceID.Text=EmptyStr then begin
     lblEdtInvoiceID.Text:='';
   end;
   FrmMain.ZQuery.SQL.Text:='INSERT INTO comingsofinvoicesongoods VALUES(NULL,CURRENT_TIMESTAMP,'''+lblEdtInvoiceID.Text+''','+IntToStr(FrmMain.counterPartieSelectedId)+','+IntToStr(FrmMain.storeHouseSelectedId)+')';
   if lblEdtInvoiceID.Text=EmptyStr then begin
     lblEdtInvoiceID.Text:='';
   end;
   FrmMain.ZQuery.ExecSQL;
   ginvoiceid:=FrmMain.LastInsertID('comingsofinvoicesongoods');
 end else begin
   if invoiceChanged then begin
     FrmMain.ZQuery.SQL.Text:='UPDATE comingsofinvoicesongoods SET invoiceid='''+lblEdtInvoiceID.Text+''',counterpartyid='+IntToStr(FrmMain.counterPartieSelectedId)+',storehouse='+IntToStr(FrmMain.storeHouseSelectedId)+' WHERE id='+IntToStr(ginvoiceid);
     FrmMain.ZQuery.ExecSQL;
   end;
 end;

 if goodsChanged then begin
   for i:=1 to StringGridGoods.RowCount-1 do begin
     if StringGridGoods.Cells[1,i]=EmptyStr then begin
       FrmMain.ZQuery.SQL.Text:='INSERT INTO comingsgoods VALUES(NULL,'+IntToStr(ginvoiceid)+','+StringGridGoods.Cells[6,i]+','+StringGridGoods.Cells[3,i]+','+StringReplace(StringGridGoods.Cells[4,i], ',', '.',[rfReplaceAll])+')';
       FrmMain.ZQuery.ExecSQL;
     end else begin
        FrmMain.ZQuery.SQL.Text:='UPDATE comingsgoods SET nomenclatureid='+StringGridGoods.Cells[6,i]+',quantity='+StringGridGoods.Cells[3,i]+',price='+StringReplace(StringGridGoods.Cells[4,i], ',', '.',[rfReplaceAll])+' WHERE id='+StringGridGoods.Cells[1,i];
        FrmMain.ZQuery.ExecSQL;
     end;
   quantity:='0';
   //////////////////////////////////////////////////
   if (StringGridGoods.Cells[1,i]=EmptyStr) then begin
      FrmMain.updateStoreHousesGoodsCount(StringGridGoods.Cells[3,i],IntToStr(FrmMain.storeHouseSelectedId),StringGridGoods.Cells[6,i]);
   end;
   /////////////////Update count of goods if changed, in nomenclature and storehouse///////////////////
   if (((StringGridGoods.Cells[1,i]<>EmptyStr)) AND (StringGridGoods.Cells[7,i]<>EmptyStr) AND (StringGridGoods.Cells[3,i]<>StringGridGoods.Cells[7,i])) then begin
     if StrToInt(StringGridGoods.Cells[7,i])<StrToInt(StringGridGoods.Cells[3,i]) then begin
       quantity:=IntToStr(StrToInt(StringGridGoods.Cells[3,i])-StrToInt(StringGridGoods.Cells[7,i]));
     end else begin
       quantity:='-'+IntToStr(StrToInt(StringGridGoods.Cells[7,i])-StrToInt(StringGridGoods.Cells[3,i]));
     end;
     if StrToInt(StringGridGoods.Cells[7,i])=StrToInt(StringGridGoods.Cells[3,i]) then begin
       quantity:='0';
     end;
     StringGridGoods.Cells[7,i]:='';
     FrmMain.updateStoreHousesGoodsCount(quantity,IntToStr(FrmMain.storeHouseSelectedId),StringGridGoods.Cells[6,i]);
   end;
   end;
 end;
 invoiceIsNew:=False;
 invoiceChanged:=False;
 goodsChanged:=False;
 refreshListOfGoods;
 checkErrors();
end;

procedure TfrmComingInvoiceElement.btnGoodsAddClick(Sender: TObject);
begin
  StringGridGoods.RowCount:=StringGridGoods.RowCount+1;
  StringGridGoods.Row:=StringGridGoods.RowCount;
  goodsEditMode:=True;
  checkErrors();
  btnGoodsSave.Enabled:=False;
  btnSave.Enabled:=False;
end;

procedure TfrmComingInvoiceElement.btnGoodsSaveClick(Sender: TObject);
begin
  goodsChanged:=True;
  goodsEditMode:=False;
  checkErrors();
end;

procedure TfrmComingInvoiceElement.btnCounterPartiesSelectClick(Sender: TObject);
begin
  frmCounterPartiesSelect.ShowModal;
  lblEdtCounterParty.Text:=FrmMain.counterPartieSelectedTitle;
  invoiceChanged:=True;
  checkErrors();
end;

procedure TfrmComingInvoiceElement.btnGoodsCancelClick(Sender: TObject);
begin
  StringGridGoods.DeleteRow(StringGridGoods.Row);
  goodsEditMode:=False;
  checkErrors();
end;

procedure TfrmComingInvoiceElement.btnGoodsDeleteClick(Sender: TObject);
var
  storeHousesGoodQuantity,res:Integer;
begin
  res:=MessageDlg('','Видалити запис?',mtConfirmation,mbYesNo,0);
  if (res=mrYes) then begin
    if ((invoiceIsNew) OR (StringGridGoods.Cells[1,StringGridGoods.Row]=EmptyStr)) then begin
      StringGridGoods.DeleteRow(StringGridGoods.Row);
    end else begin
      storeHousesGoodQuantity:=FrmMain.tableQuantity('nomenclatureonstorehouses','nomenclatureid='+StringGridGoods.Cells[6,StringGridGoods.Row]+' AND storehouseid='+IntToStr(FrmMain.storeHouseSelectedId));
      if (storeHousesGoodQuantity<0) then begin
        ShowMessage('Невистачає товару на складі'+#13+'На складі '+IntToStr(storeHousesGoodQuantity)+' одиниць товару');
        FrmMain.history('Вихідна накладна','Спроба встановити невідповідну кількість товару'+#13+'На складі '+IntToStr(storeHousesGoodQuantity)+' одиниць товару');
      end else begin
        FrmMain.ZQuery.SQL.Text:='DELETE FROM comingsgoods WHERE id='+StringGridGoods.Cells[1,StringGridGoods.Row];
        FrmMain.ZQuery.ExecSQL;
        FrmMain.updateStoreHousesGoodsCount('-'+StringGridGoods.Cells[3,StringGridGoods.Row],IntToStr(FrmMain.storeHouseSelectedId),StringGridGoods.Cells[6,StringGridGoods.Row]);
        StringGridGoods.DeleteRow(StringGridGoods.Row);
        FrmMain.DSComingGoodsView.DataSet.Refresh;
        updateAllCount;
      end;
    end;
    checkErrors();
  end;
end;

end.

